package tool

import (
	"MoSkeleton/config/consts"
	"MoSkeleton/framework/core/dto/request"
	"MoSkeleton/framework/core/dto/response"
	"MoSkeleton/framework/utils"
	tool2 "MoSkeleton/models/tool"
	"MoSkeleton/services/base"
	"MoSkeleton/services/tool/logic"
	tool3 "MoSkeleton/web/pogos/request/tool"
	"MoSkeleton/web/pogos/response/tool"
	"gorm.io/gorm"
)

type GenDatasourceService struct {
	base.BaseService
}

func (d *GenDatasourceService) GetDatasourcePage(pageReq *tool3.GenDatasourcePageReq) (*response.PageResult, error) {
	db := d.getDatasourceVo(nil, pageReq)
	var total int64
	itemsResp := make([]*tool.GenDatasourceItemResp, 0)

	if err := db.Count(&total).Offset(pageReq.Offset()).Limit(pageReq.Limit()).Find(&itemsResp).Error; err != nil {
		return nil, err
	}
	pageResult := response.NewFromPageInfoAndData(&pageReq.PageInfo, &itemsResp, total)
	return pageResult, nil
}

func (d *GenDatasourceService) GetDatasourceById(id uint64) (*tool.GenDatasourceDetailResp, error) {
	db := d.GetDb(nil).Table("gen_datasource gd")
	var itemResp tool.GenDatasourceDetailResp
	if err := db.Where("gd.id = ?", id).First(&itemResp).Error; err != nil {
		return nil, err
	}
	if itemResp.DbPasswd != "" {
		var err error
		itemResp.DbPasswd, err = utils.Sm4Decrypt(utils.Store_Sm4Key, itemResp.DbPasswd)
		if err != nil {
			return nil, err
		}
	}
	return &itemResp, nil
}

func (d *GenDatasourceService) AddDatasource(addReq *tool3.GenDatasourceAddReq) (bool, error) {
	datasource := new(tool2.GenDatasource)
	if err := utils.CopyStruct(datasource, addReq); err != nil {
		return false, err
	}
	if datasource.DbPasswd != "" {
		datasource.DbPasswd, _ = utils.Sm4Encrypt(utils.Store_Sm4Key, datasource.DbPasswd)
	}
	result := d.GetDb(nil).Create(datasource)
	return result.RowsAffected > 0, result.Error
}

func (d *GenDatasourceService) DeleteDatasource(ids *[]string) (bool, error) {
	return d.DeleteByIds(nil, new(tool2.GenDatasource), ids)
}

func (d *GenDatasourceService) UpdateDatasource(updateReq *tool3.GenDatasourceUpdateReq) (bool, error) {
	datasource := new(tool2.GenDatasource)
	if err := utils.CopyStruct(datasource, updateReq); err != nil {
		return false, err
	}
	if datasource.DbPasswd != "" {
		datasource.DbPasswd, _ = utils.Sm4Encrypt(utils.Store_Sm4Key, datasource.DbPasswd)
	}
	oldDatasource := new(tool2.GenDatasource)
	if err := d.GetDb(nil).Where("id = ?", updateReq.ID).First(oldDatasource).Error; err != nil {
		return false, err
	}
	datasource.CreatedAt = oldDatasource.CreatedAt
	datasource.CreatedBy = oldDatasource.CreatedBy
	result := d.GetDb(nil).Save(datasource)
	return result.RowsAffected > 0, result.Error
}

func (d *GenDatasourceService) ChangeStatus(changeStatusReq *request.ChangeStatusReq) error {
	datasource := new(tool2.GenDatasource)
	datasource.ID = changeStatusReq.ID
	datasource.Status = changeStatusReq.Status
	return datasource.ChangeStatus(nil, datasource)
}
func (d *GenDatasourceService) TestConnection(addReq *tool3.GenDatasourceAddReq) error {
	datasourcePogo := new(logic.DatasourcePogo)
	if err := utils.CopyStruct(datasourcePogo, addReq); err != nil {
		return err
	}
	return logic.TestConnection(datasourcePogo)
}

func (d *GenDatasourceService) GetAllDatasources() ([]*tool.GenDatasourceSimpleItemResp, error) {
	datasources := make([]*tool.GenDatasourceSimpleItemResp, 0)
	if err := d.GetDb(nil).Model(&tool2.GenDatasource{}).Where("status=?", consts.U_NORMAL).Order("list_order asc").Find(&datasources).Error; err != nil {
		return nil, err
	}
	return datasources, nil
}
func (d *GenDatasourceService) getDatasourceVo(tx *gorm.DB, pageReq *tool3.GenDatasourcePageReq) *gorm.DB {
	db := d.GetDb(tx).Table("gen_datasource gd")
	if pageReq.Status != "" {
		db.Where("gd.status = ?", pageReq.Status)
	}
	if pageReq.DatasourceName != "" {
		db.Where("gd.datasource_name like ?", "%"+pageReq.DatasourceName+"%")
	}
	beginTime, ok := pageReq.GetParamValue("beginTime")
	if ok && beginTime != "" {
		if beginTime = pageReq.FormatBeginTime(beginTime); beginTime != "" {
			db.Where("gc.created_at >= ?", beginTime)
		}
	}
	endTime, ok := pageReq.GetParamValue("endTime")
	if ok && endTime != "" {
		if endTime = pageReq.FormatEndTime(endTime); endTime != "" {
			db.Where("gc.created_at <= ?", endTime)
		}
	}
	return db
}
